use base_data::channel::{event::ChannelEvent, ChannelState, CommandMsg, EndReason};
use tools::{utils::gen_id::get_now_duration, ResultEx, ResultNull};
use tracing::debug;

use crate::sip2::{
	dialog::{
		dialog::{Dialog, DialogState},
		sipdata::SipData,
		INV_OVER, MAX_TRY_TIME, T1, WAIT_REPEAT_TIME,
	},
	SipDirection,
};

use super::{send_wait_resp, SipTimeOver, SipTransactionState, WaitSipMessage};

#[inline]
pub fn start_tran(dialog: &mut Dialog) {
	dialog.set_tran_state(SipTransactionState::Trying);
	dialog.start_time = get_now_duration();
	dialog.wait_resp_method = WaitSipMessage::None;
	dialog.retry_time = T1;
	
	if dialog.over_time == SipTimeOver::Zero {
		dialog.over_time = SipTimeOver::TranOvertime(INV_OVER);
	}

	//在这里会设置重发的相关状态.上面不需要设置了
	match dialog.last_send_bytes.take() {
		Some(b) => send_wait_resp(dialog, WaitSipMessage::SuccessOrFailure, b),
		None => dialog.wait_resp_method = WaitSipMessage::SuccessOrFailure,
	}

	//这是主动向对端发送结束的包
	if dialog.state == DialogState::NeedKill {
		dialog.send_to_business(ChannelEvent::ChannelCallState(
			dialog.id,
			ChannelState::Hangup,
		));
		dialog.send_to_business(ChannelEvent::ChannelHangup(
			dialog.id,
			EndReason::InitiativeHangup,
		));
	}
}

///处理事务收到的传输层的消息
#[inline]
pub fn handle_tran_msg(dialog: &mut Dialog, sip_data: SipData) -> ResultNull {
	match sip_data.direction {
		SipDirection::Response(r) => match (r.into(), dialog.tran_state()) {
			//根据sip协议,收到1xx临时消息后,还是要重发的.周期改变
			(100..=199, SipTransactionState::Trying) | (100..=199, SipTransactionState::Proceeding) => {
				dialog.retry_time = MAX_TRY_TIME;
				dialog.last_send_bytes = None;
				dialog.set_tran_state(SipTransactionState::Proceeding);
			}
			//注册操作需要另行处理
			(200..=699, SipTransactionState::Trying)
			| (200..=699, SipTransactionState::Callin)
			| (200..=699, SipTransactionState::Proceeding) => {
				dialog.start_time = get_now_duration();
				dialog.last_send_bytes = None;
				dialog.over_time = SipTimeOver::Finish(WAIT_REPEAT_TIME);
				dialog.wait_resp_method = WaitSipMessage::None;
				dialog.set_tran_state(SipTransactionState::Terminated);
			}
			_ => debug!(
				"non_inv_client收到无效回复消息.sip:{:?},状态:{:?}",
				sip_data,
				dialog.tran_state()
			),
		},
		SipDirection::Request(_) => debug!("inv_cli不应该收到请求"),
	}

	Ok(())
}

///处理事务收到的命令消息
#[inline]
pub fn handle_command_msg(_dialog: &mut Dialog, cmd_msg: CommandMsg) -> ResultNull {
	debug!("non_inv_cli 收到一个无效的命令消息.msg:{cmd_msg:?}");
	Ok(())
}

///处理事务结束的操作..
/// 返回true表示事务结束时dialog同时结束.
/// 清理当前事务相关数据
#[inline]
pub fn end_tran(dialog: &mut Dialog) -> ResultEx<bool> {
	dialog.last_send_bytes = None;
	//目前来看非inv事务没有保存dialog的必要
	Ok(true)
}

#[inline]
pub fn handle_time_over(dialog: &mut Dialog, to: SipTimeOver) -> ResultNull {
	match to {
		//只要是超时,则不算成功创建dialog
		SipTimeOver::TranOvertime(_) => {
			dialog.set_tran_state(SipTransactionState::Terminated);
		}
		SipTimeOver::Retry(_) => {
			dialog.retry_send()?;
		}
		_ => {}
	}

	//超时以后的判断.
	if dialog.tran_state() == SipTransactionState::Completed {
		dialog.set_tran_state(SipTransactionState::Terminated);
	}

	Ok(())
}
